package com.laoniu.biz;

import cn.hutool.core.convert.Convert;
import com.google.common.collect.Lists;
import com.laoniu.dto.request.MenuFormRequestDto;
import com.laoniu.dto.request.MenuListDto;
import com.laoniu.dto.response.MenuResponseDto;
import com.laoniu.entity.SecurityUser;
import com.laoniu.entity.SysMenu;
import com.laoniu.service.sys.SysMenuService;
import com.laoniu.utils.LocalDateTimeUtils;
import com.laoniu.utils.SpringSecurityUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MenuBiz {

    @Autowired
    private SysMenuService menuService;

    /**
     * 新增菜单
     * @param requestDto
     */
    public void saveMenu(MenuFormRequestDto requestDto){
        SecurityUser user = SpringSecurityUtils.getUser();
        SysMenu menu = Convert.convert(SysMenu.class, requestDto);
        menu.setCreateTime(LocalDateTime.now());
        menu.setOperateUserId(user.getId());
        menu.setOperateUserName(user.getName());
        menuService.save(menu);
    }

    /**
     * 修改菜单
     * @param requestDto
     */
    public void updateMenu(MenuFormRequestDto requestDto){
        SecurityUser user = SpringSecurityUtils.getUser();
        SysMenu menu = menuService.getById(requestDto.getId());
        if (Objects.isNull(menu)){
            return;
        }
        menu.setOperateUserName(user.getName());
        menu.setOperateUserId(user.getId());
        menu.setName(requestDto.getName());
        menu.setIcon(requestDto.getIcon());
        menu.setType(requestDto.getType());
        menu.setAuth(requestDto.getAuth());
        menu.setRouter(requestDto.getRouter());
        menu.setView(requestDto.isView());
        menu.setParentId(requestDto.getParentId());
        menu.setOrderNum(requestDto.getOrderNum());
        menuService.updateById(menu);
    }

    /**
     * 查询列表
     * @param dto
     * @return
     */
    public List<MenuResponseDto> menuList(MenuListDto dto){

        if (Objects.isNull(dto.getParentId())){
            dto.setParentId(0L);
        }
        List<SysMenu> list = menuService.selectByParentId(dto.getParentId());
        List<MenuResponseDto> resultList = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(list)){
            for (SysMenu menu : list) {
                MenuResponseDto responseDto = convertMenuDto(menu);
                responseDto.setHasChildren(dto.getParentId() == 0L);
                resultList.add(responseDto);
            }
        }
        return resultList;
    }

    /**
     * 树形列表
     * @return
     */
    public List<MenuResponseDto> treeList() {
        List<SysMenu> menuList = menuService.selectList();
        return convertTree(menuList);
    }

    public List<MenuResponseDto> convertTree(List<SysMenu> menuList){
        List<MenuResponseDto> result = Lists.newArrayList();
        if (CollectionUtils.isEmpty(menuList)){
            return result;
        }
        Map<Long, List<SysMenu>> menuMap = menuList.stream().collect(Collectors.groupingBy(SysMenu::getParentId));
        List<SysMenu> sysMenus = menuMap.get(0L);
        if (CollectionUtils.isEmpty(sysMenus)){
            return result;
        }
        for (SysMenu menu : sysMenus) {
            MenuResponseDto responseDto = convertMenuDto(menu);
            List<SysMenu> childrenMenuList = menuMap.get(menu.getId());
            if (CollectionUtils.isNotEmpty(childrenMenuList)){
                List<MenuResponseDto> childrenList = Lists.newArrayList();
                for (SysMenu sysMenu : childrenMenuList) {
                    MenuResponseDto childrenDto = convertMenuDto(sysMenu);
                    childrenList.add(childrenDto);
                }

                responseDto.setChildren(childrenList);
            }
            result.add(responseDto);
        }
        return result;
    }

    private MenuResponseDto convertMenuDto(SysMenu menu){
        MenuResponseDto responseDto = new MenuResponseDto();
        responseDto.setId(menu.getId());
        responseDto.setRouter(menu.getRouter());
        responseDto.setName(menu.getName());
        responseDto.setIcon(menu.getIcon());
        responseDto.setAuth(menu.getAuth());
        responseDto.setType(menu.getType());
        responseDto.setOrderNum(menu.getOrderNum());
        responseDto.setView(menu.isView());
        responseDto.setParentId(menu.getParentId());
        responseDto.setCreateTime(LocalDateTimeUtils.localDateTimeToLong(menu.getCreateTime()));
        responseDto.setOperateUserId(menu.getOperateUserId());
        responseDto.setOperateUserName(menu.getOperateUserName());
        return responseDto;
    }

    public List<MenuResponseDto> userMenuList() {
        SecurityUser user = SpringSecurityUtils.getUser();
        List<SysMenu> menuList;
        if (user.isAdmin()){
            menuList = menuService.listAll();
        }else {
            menuList = menuService.selectMenuByUserId(user.getId());
            Set<Long> menuIdSet = menuList.stream().map(SysMenu::getId).collect(Collectors.toSet());
            List<SysMenu> addList = Lists.newArrayList();
            for (SysMenu menu : menuList) {
                if (!menuIdSet.contains(menu.getParentId()) && 0 != menu.getParentId()){
                    SysMenu parentMenu = menuService.getById(menu.getParentId());
                    menuIdSet.add(parentMenu.getId());
                    addList.add(parentMenu);
                }
            }
            if (CollectionUtils.isNotEmpty(addList)){
                menuList.addAll(addList);
            }
            menuList = menuList.stream().sorted(Comparator.comparing(SysMenu::getOrderNum)).collect(Collectors.toList());
        }
        return convertTree(menuList);
    }
}
